/*
* ============================================================================
*  Name        : example_001.cpp
*  Part of     : Finite state machine examples
*  Description : Hello World! 
*  Version     : %version: %
*  
*
* ============================================================================
*/
#include "example_001.h"
#include "example_001.hxx" // State machine source code is here

/**
 * @file example_001.cpp
 *
 * @details
 * Hello world example. Start point to create your own state machine. \b 'sync' mode. 
 *
 * @ingroup StateMachineExamples
 *
 * \mainpage
 *
 * @li Knowledge is a collection of stored and retained information
 * @li Intelligence is an abilty to find associations between things in sorted form by the likelyhood in a particular
 * context
 * @li Things are connected == linked with each other by qualities == properties == associations
 * @li One thing is connected to another via a number of associations
 * @li Agregation mechanisms of things and associations are the same
 * @li Objects and associations are dynamic in nature and may change in time
 * that is depicted by the finite state machine notation presented in the documenation
 *
 * Take a look at the examples one by one in \b Modules section. Each introduce new functionality or use case.
 * @li example_101.h Objects associations
 * @li example_001.h Hello world state machine. \b 'sync' mode. 
 * @li example_002.h Time limited states.
 * @li example_003.h More complex state machine. \b 'async', \b 'async_batch' modes. Multiple instances.
 * @li example_004.h Event handler example. Event priorities.
 * @li example_005.h Parent-Child relationship. Forsed state machine termination.
 * @li example_006.h \b 'user_dispatched' mode. Dispatching state machine in existing event handling systems like Qt.
 * @li example_007.h Message exchange between two state machines.
 * @li example_008.h Use of file as a source code 
 * @li example_009.h User input processing
 *
 * In order to use state machine framework (sea) user have to 
 * @li derive a class from sea::StateMachine
 * @li declare a list of events
 * @li declare a list of action functions
 * @li declare a state machine
 * 
 * Example of the state machine source code:<br>
 * @code
 *    SM_DECLARE
 *    (
 *        HelloTheWorld_src,  
 *        HelloTheWorld       
 *        sync                    
 *        {
 *            Exceptions          
 *            {
 *                Ev_Sys_Terminate        exit                nojump  
 *            }
 *            Main
 *            {
 *                Ev_Sys_OnEntry          say_hello_world     nojump
 *                Ev_Sys_OnEntry          exit                nojump
 *            }
 *        } 
 *    );
 *  
 * @endcode
 *
 * The header consists of: <br>
 * @li \b Source \b code \b name
 * @li \b User \b class
 * @li \b Execution \b mode
 *
 * @code
 *    SM_DECLARE
 *    (
 *        HelloTheWorld_src,  
 *        HelloTheWorld       
 *        sync                    
 * @endcode
 *
 * Execution modes specified in the source code:
 * @li \b sync
 * @li \b parser
 * @li \b async
 * @li \b async_batch
 * @li \b user_dispatched
 *
 * Runtime execution modes used with \b start( ) API:
 *      @li \b RunDefault,                     ///< Exec mode specified in state machine body
 *      @li \b RunSync,                        ///< Exec in sync mode. start( ) will not return until state machine is finished
 *      @li \b RunParser,                      ///< same as RunSync, but no waiting for external events. Self driven state machine.
 *      @li \b RunAsync,                       ///< Exec all specified state machines in async mode in a separate thread
 *      @li \b RunAsyncBatch,                  ///< Exec all specified state machines in one new thread 
 *      @li \b RunWithParent,                  ///< Exec all specified state machines in the parent's thread
 *      @li \b RunDispatched                   ///< Exec state machine via user controlled \b dispatch( ) API
 * API allows user to override execution mode specified in the source code.
 *
 * The header is followed by the array of states. In our example 
 * @li \b Exception
 * @li \b Main
 *
 * Every state consist of a number of event records 
 *     @li \b event_id   \b action_function   \b next_state_name
 *
 * @code
 *     Main
 *     {
 *         Ev_Sys_OnEntry          say_hello_world     nojump
 *         Ev_Sys_OnEntry          exit                nojump
 *     }
 * @endcode
 *
 * As you can see in the example above a number of action functions can be called sequentially on a single event <br>
 * The restriction is that they have to be \b one \b after \b another. The following is INCORRECT:
 *
 * @code
 *     Main
 *     {
 *         Ev_Sys_OnEntry          say_hello_world     nojump
 *         Ev_Int_MyEvent          do_something        nojump
 *         Ev_Sys_OnEntry          exit                nojump   // This record will not be processed
 *     }
 * @endcode
 *
 * State name is followed by optional \b life \b cycle descriptor
 *
 * Example \b 1 ( state with timer ): <br>
 *
 * @code
 *    Main 300 3
 * @endcode 
 *
 * This means that every \b 300ms \b Ev_Sys_Heartbeat event will be fired by the framework's timer except 
 * the last one: \b Ev_Sys_LastHeartbeat. <br> In the example above event sequence will be:  <br>
 *
 * @code
 *     300ms
 *     Ev_Sys_Heartbeat
 *     300ms
 *     Ev_Sys_Heartbeat
 *     300ms
 *     Ev_Sys_LastHeartbeat
 * @endcode
 *
 * Example \b 2 ( unlimited heart beats count ):<br>
 *
 * @code
 *     Main 1000 0
 *     or 
 *     Main 1000 
 * @endcode 
 *
 * Only \b Ev_Sys_Heartbeat event will be fired every 1000ms. State would exit on some other user defined event.
 *
 * Example \b 3 ( timer-less state ):<br>
 *
 * @code
 *     Main 0 0 
 *     or 
 *     Main  
 * @endcode 
 *
 * For such states only user defined events can trigger transition to another state.<br>
 *
 * Example \b 4 ( counting state ):<br>
 *
 * @code
 *     Main 0 100
 *     {
 *          Ev_Sys_OnEntry          do_init             next
 *          Ev_Sys_Heatbeat         do_foo              next
 *          Ev_Sys_LastHeatbeat     do_last_thing       AnotherState
 *     }
 * @endcode 
 *
 * \b next keyword used in such state in the \b next_state field causes increase of the state counter. <br>
 * That would trigger \b Ev_Sys_Heartbeat event right away. On counter reaching 100, <br>
 * \b Ev_Sys_LastHeartbeat event will be fired.<br>
 *
 * There is a number of events fired by the framework: <br>
 *      @li \b Ev_Sys_OnEntry              ///< on state entry 
 *      @li \b Ev_Sys_Heartbeat            ///< heart beat timeout 
 *      @li \b Ev_Sys_LastHeartbeat        ///< last heart beat timeout exipred
 *      @li \b Ev_Sys_ChildTerminated      ///< child state machine has been stopped
 *      @li \b Ev_Sys_ParentTerminated     ///< parent state machine has been stopped
 *      @li \b Ev_Sys_Terminate            ///< command/event to terminate state machine
 *
 * User can generate @li \b Ev_Sys_Terminate to instruct other state machine to exit, unless there is another <br>
 * protocol in place between them. The framework does not apply any limitation in that respect.<br>
 *
 * In parent child relationship the following system events are generated to notify each other about termination. <br>
 * @li \b Ev_Sys_ChildTerminated <br>
 * @li \b Ev_Sys_ParentTerminated <br>
 *
 * Other conventions and rules:
 *  @li \b exit      in \b action_function field is the state machine termination function predefined by the framework
 *  @li \b null      in \b action_function filed means no action is required.
 *  @li \b nojump    in \b next_state field means no transition is required.
 *  @li \b next      in \b next_state field indicates, that the current state is a Counting State. See example above.
 *
 * Very first state in the state machine source code is treated as an \b Exception state. User can choose another name. <br>
 * All events not processed in the current state get in this state. If the event is not listed in the \b Exception state <br>
 * it will be ignored. <br> User may choose to have only \b Exception state, which will act as a simple event handler.
 *
 * @code
 *     Exceptions
 *     {
 *         Ev_Ext_say_hello        say_hello       nojump
 *         Ev_Ext_say_sea          say_sea         nojump
 *         Ev_Ext_say_world        say_world       nojump
 *     }
 * @endcode
 *
 * Framework has 3 levels of events priorities.
 *      @li \b Ev_Ext_*  - lowest. Declared with \b EVENT_EXT( ) macros as part of class definition.
 *      @li \b Ev_Int_*  - lower. Declared with \b EVENT_INT( ) macros  as part of class definition.
 *      @li \b Ev_Sys_*  - highest. Reserved by the framework and cannot be declared by user.
 *
 * Example of event declaration in the user class: <br>
 * @code
 * public:
 *     EVENT_EXT( HelloTheWorld, Ev_Ext_myEvent1 ); 
 *     EVENT_EXT( HelloTheWorld, Ev_Ext_myEvent2 ); 
 *
 * private:
 *     EVENT_INT( HelloTheWorld, Ev_Int_myEvent1 ); 
 *     EVENT_INT( HelloTheWorld, Ev_Int_myEvent2 ); 
 * @endcode
 *
 * \b StateMachine::start API allows to launch a number of state machines at the same time. See \b StateMachine::start.
 *
 * Example of the Hello World class: <br>
 * @code
 *     class HelloTheWorld : public StateMachine
 *     {
 *     public:
 *          HelloTheWorld::HelloTheWorld( ) : StateMachine( STATEMACHINE_NAME ){ }
 *          ACT( HelloTheWorld, say_hello_world );
 *     };
 *
 *     ACT_IMPL( HelloTheWorld, say_hello_world )
 *     {
 *        SEA_UNUSED_PARAM( );
 *        SEA_TRACE( "\n<<<< Hello SEA World >>>>\n" ); 
 *     }
 * @endcode
 *
 * And finaly this is how to instantiate and run the state machine: <br>
 * @code
 *     // Instantiate state machine
 *     // Compile the source code or reuse the compiled one
 *     // Execute state machine. The function will not leave until state machine is finished in 'sync' and 'parser' modes
 *     // Release local state machine reference
 *     // Terminate state machine engine at the application exit. It also terminates all state machines.
 *     int main( )
 *     {
 *          HelloTheWorld* sm = NEW HelloTheWorld;
 *          sm->create( 0, HelloTheWorld_src );
 *          sm->start( );
 *          sm->release_ref( );
 *          Engine::terminate( );
 *     }
 * @endcode
 *
 */
using namespace sea_examples;

// ----------------------------------------------------------------------------
// Hello world using states with timers
// ----------------------------------------------------------------------------
void sea_examples::launch_example_001( )
{
    SEA_TRACE_ENTRY( );

    // 1. Instantiate state machine
    // 2. Compile the source code or reuse the compiled one
    // 3. Execute state machine. The function will not leave until state machine is finished in 'sync' and 'parser' modes
    // 4. Release local state machine reference
    // 5. Terminate state machine engine at the application exit. It also terminates all state machines.
    {
        sea::ref< HelloTheWorld_001 > sm;
        sm << NEW HelloTheWorld_001;
        if ( sm->create( 0, HelloTheWorld_001_src ) != eOk ){ /* See Error codes */ }
        if ( sm->start( ) != eOk ){ /* See Error codes */ }
    }
    Engine::terminate( );
}

// ----------------------------------------------------------------------------
// Ctor. Base StateMachine class requires user class name to register in the 
// framework meta system
// ----------------------------------------------------------------------------
HelloTheWorld_001::HelloTheWorld_001( ) : 
    StateMachine( STATEMACHINE_NAME )
{
}

// ----------------------------------------------------------------------------
// Action function. Print 'Hello'
// ----------------------------------------------------------------------------
ACT_IMPL( HelloTheWorld_001, say_hello_world )
{
    SEA_UNUSED_PARAM( );
    SEA_TRACE( "\n<<<< Hello SEA World >>>>\n" ); 
}
